package psd.model.Prolog.Converters;

import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.Type;

import psd.model.IConverter;
import psd.model.Prolog.FactGenerationToolbox;
import psd.model.Prolog.PrologConverter;

public class PrologClassInstanceCreationConverter extends PrologConverter implements
IConverter<ClassInstanceCreation> {

	public PrologClassInstanceCreationConverter(FactGenerationToolbox toolbox) {
		super(toolbox);
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean convert(ClassInstanceCreation node) {
		
		        ITypeBinding binding = node.getType().resolveBinding();
		        String typeName = "";
		        PrologCommon.generatePackageFactIfNecessary(binding,generationToolBox);
		        Type type = node.getType();
		        Name name = null;
		        if(type instanceof SimpleType)
		        {
		            name = ((SimpleType)type).getName();
		        } else
		        {
		            if(type instanceof ParameterizedType)
		            {
		                //throw new RuntimeException("generics not supported yet");
		            	writeParametrizedType(node);
		            	typeName = ((ParameterizedType)type).getType().resolveBinding().getName();
		            }else
		            name = ((QualifiedType)type).getName();
		        }
		        String arg1 = idResolver.getIDs(node.arguments());
		        if(typeName == "")
		        	typeName = idResolver.getID(name.resolveBinding());
		        String def = idResolver.getID(node.getAnonymousClassDeclaration());
		        ITypeBinding typeBinding = node.resolveTypeBinding();
		        String constructor = null;
		        if(typeBinding == null)
		        {
		            constructor = "resolve_failed";
		        } else
		        {
		            constructor = (String) generationToolBox.getSyntheticConstructorIds().get(typeBinding);
		        }
		        if(constructor == null)
		        {
		            constructor = idResolver.getID(node.resolveConstructorBinding());
		        }
		        Expression expr = node.getExpression();
		        String enclosing = idResolver.getID(expr);
		        if(node.getAnonymousClassDeclaration() != null)
		        {
		            constructor = "'null'";
		        }
		        String args[] = {
		            constructor, arg1, typeName, def, enclosing, this.getFilePath(node), this.getLineNumber(node)
		        };
		        createBodyFact(node, "newClassT", args);
		        return true;
		    
	}
	private void writeParametrizedType(ClassInstanceCreation node){
		ParameterizedType paramType = (ParameterizedType)node.getType();
		List typearguments = paramType.typeArguments();
		for (Object argument : typearguments) {
			if(argument instanceof Type){
				Type type = (Type)argument;
			if(type.isSimpleType()){
				Name name = ((SimpleType)type).getName();
				String typeName = idResolver.getID(name.resolveBinding());
				  String constructor = idResolver.getID(node.resolveConstructorBinding());
				  String args[] = {
						  constructor, typeName, this.getFilePath(node), this.getLineNumber(node)
				        };
				  createBodyFact(node, "parametrizedTypeT", args);
			} 
			}
		}
			
	}

}
